import { useState, useEffect, useRef, Dispatch, SetStateAction, useCallback } from "react";

type UseStateIfMountedReturn<S> = [S, Dispatch<SetStateAction<S>>];

/**
 * 自定义hooks-之解决组件卸载后更新state问题
 */
function useStateIfMounted<T>(initialState: T): UseStateIfMountedReturn<T> {
  const [state, setState] = useState<T>(initialState);
  const isMountedRef = useRef<boolean>(true);

  useEffect(
    () => () => {
      // 组件卸载
      isMountedRef.current = false;
    },
    []
  );

  /**
   * 更新函数-使用useCallback使之函数引用保持不变
   */
  const setStateIfMounted: Dispatch<SetStateAction<T>> = useCallback((data: SetStateAction<T>) => {
    if (isMountedRef.current === true) {
      setState(data);
    }
  }, []);

  return [state, setStateIfMounted];
}

export default useStateIfMounted;
